<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 剩余参数和 arguments对象之间的区别主要有三个：

        // 剩余参数只包含那些没有对应形参的实参，而 arguments 对象包含了传给函数的所有实参。
        // arguments对象不是一个真正的数组，而剩余参数是真正的 Array实例，也就是说你能够在它上面直接使用所有的数组方法，比如 sort，map，forEach或pop。
        // arguments对象还有一些附加的属性 （如callee属性）。

        //【1】es6引入剩余参数概念，来减少由参数引起的样板代码。
        // Before rest parameters, the following could be found:
        function f(a, b) {
            var args = Array.prototype.slice.call(arguments, f.length);

            // …
        };

        // to be equivalent of

        function f(a, b, ...args) {

        };
        //【2】剩余参数可以被解包到不同变量中。
        function f(...[a, b, c]) {
            return a + b + c;
        };

        var res1 = f(1)
        console.log(res1); // NaN (b and c are undefined)【此处实参地方展开运算符处没有参数】
        var res2 = f(1, 2, 3)
        console.log(res2); // 6
        var res3 = f(1, 2, 3, 4)
        console.log(res3); // 6 (the fourth parameter is not destructured)

        function multiply(multiplier, ...theArgs) {
            console.log(theArgs); //[1, 2, 3]
            return theArgs.map(function(element) {
                return multiplier * element; // [2, 4, 6]
            });
        };

        var arr = multiply(2, 1, 2, 3);
        console.log(arr);
        // 【2-1】
        function fun1(...theArgs) {
            console.log(theArgs.length);
        }

        fun1(); // 弹出 "0", 因为theArgs没有元素
        fun1(5); // 弹出 "1", 因为theArgs只有一个元素
        fun1(5, 6, 7); // 弹出 "3", 因为theArgs有三个元素
        // 【3】在剩余参数上使用任意的数组方法，而arguments对象不可以
        function sortRestArgs(...theArgs) {
            var sortedArgs = theArgs.sort();
            return sortedArgs;
        }

        console.log(sortRestArgs(5, 3, 7, 1)); // 弹出 1,3,5,7

        function sortArguments() {
            var sortedArgs = arguments.sort();
            return sortedArgs; // 不会执行到这里
        }

        console.log(sortArguments(5, 3, 7, 1)); // 抛出TypeError异常:arguments.sort is not a function
        // 【4】怎么在arguments上使用Array方法
        function sortArguments() {
            var args = Array.prototype.slice.call(arguments);
            var sortedArgs = args.sort();
            return sortedArgs;
        }
        console.log(sortArguments(5, 3, 7, 1)); // shows 1, 3, 5, 7
    </script>
</body>

</html>